package com.evil.common.core.util;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.evil.common.core.constant.RedisConstant;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.Set;

/**
 * 缓存工具类
 *
 * @author liyang
 * @date 2022-08-08 00:00
 */
@Slf4j
@Component
@AllArgsConstructor
public class CacheUtil {

    private final RedisUtil redisUtil;

    /**
     * 禁止使用缓存
     */
    public void cantUseCache() {
        redisUtil.set(RedisKeyUtil.requestUuidClearCache(), true);
    }

    /**
     * 记录需要清理会话级别 缓存 的key
     *
     * @param key key
     */
    public void addClearRequestCache(String key) {
        redisUtil.sSetAndTime(RedisKeyUtil.requestUuidClearCache(), RedisConstant.REQUEST_UUID_EXPIRE_IN_SECOND, key);
    }

    /**
     * 记录需要清理会话级别 缓存 的key
     *
     * @param keys keys
     */
    public void addClearRequestCache(Collection<String> keys) {
        redisUtil.sSetAndTime(RedisKeyUtil.requestUuidClearCache(), RedisConstant.REQUEST_UUID_EXPIRE_IN_SECOND, keys.toArray(new Object[]{}));
    }

    /**
     * 清理会话级别缓存（必须提交事务后再清理）
     *
     * @param runnable runnable
     */
    @Transactional(rollbackFor = Exception.class)
    public void clearRequestCache(Runnable runnable) {
        try {
            runnable.run();
        } catch (Exception e) {
            log.error("【回调操作】，失败原因", e);
            throw e;
        } finally {
            Set<Object> set = redisUtil.sGet(RedisKeyUtil.requestUuidClearCache());
            log.info("【清理会话级别缓存】，keys:{}", JSON.toJSONString(set));
            if (CollectionUtil.isNotEmpty(set)) {
                List<String> keys = StreamUtil.transListT(set, e -> (String) e);
                redisUtil.del(keys);
            }
        }
    }
}
